#include <vector>
#include <thread>
#include <future>  
#include <iostream>
#include <string>
#include "LyricUi.h"
#include "kugou.h"
#include "utils.h"
#include "resources.h"

// - Global

char *locale_lang = setlocale(LC_CTYPE, NULL);


// - Config widgets

GtkWindow  *ConfigWindow;
GtkBuilder  *builder;
GtkColorButton *Background_color;
GtkColorButton *Highlight_color;
GtkColorButton *Text_color;
GtkRadioButton *Align_left;
GtkRadioButton *Align_center;
GtkRadioButton *Align_right;
GtkSpinButton *Highlight_line;
GtkCheckButton *Check_bold;
GtkSpinButton *Edge;
GtkButton  *Apply;
GtkButton  *Cancel;
GtkButton  *OK;
GtkLabel  *Background_color_label;
GtkLabel  *Text_color_label;
GtkLabel  *Highlight_color_label;
GtkLabel  *Align_label;
GtkLabel  *Highlight_line_label;
GtkLabel  *Edge_label;

int Align_int_value;
int Check_bold_int_value;

// - Search widgets

GtkWindow   *SearchWindow;
GtkButton   *Save;
GtkButton   *Search;
GtkButton   *Exit;
GtkEntry   *Artist_input;
GtkEntry   *Song_input;
GtkEntry   *Album_input;
GtkTreeStore  *treeStore;
GtkTreeView   *SongsTree;
GtkTreeViewColumn *Column_artist;
GtkTreeViewColumn *Column_song;
GtkTreeViewColumn *Column_album;
GtkTreeViewColumn *Column_source;
GtkTreeViewColumn *Column_searchid;
GtkTreeSelection *selection;
GtkCellRenderer  *artists;
GtkCellRenderer  *songs;
GtkCellRenderer  *albums;
GtkCellRenderer  *sources;
GtkCellRenderer  *searchids;
GtkLabel   *PreViewLyrics;
GtkLabel   *Artist_label;
GtkLabel   *Song_label;
GtkLabel   *Album_label;

struct parsed_lyrics selected_lyrics = {g_strdup(""), FALSE};

GtkTreeIter iter_populate;

// - Edit widgets

GtkWindow   *EditWindow;
GtkButton   *Edit_apply;
GtkButton   *Edit_cancel;
GtkButton   *Edit_OK;
GtkTextView   *Text_view_lyrics_editor;
GtkLabel   *Playback_time;
GtkButton   *Plus_time;
GtkButton   *Minus_time;
GtkButton   *Apply_offset;
GtkButton   *Insert_timestamp;
GtkCheckButton  *Check_sync;
GtkButton   *Backward;
GtkButton   *Pause_play;
GtkButton   *Forward;
GtkLabel   *Sync_label;
GtkLabel   *Sync_or_not_label;


GtkTextBuffer  *refBuffer;

//---------------------------------------------------------------------
//******************* ConfigWindow ************************************
//---------------------------------------------------------------------

void on_Background_color_color_set (GtkColorButton *c) {
    GdkRGBA color;
    int Red, Green, Blue;
    gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(c), &color);
    Red = color.red*255 + 0.5;
    Green = color.green*255 + 0.5;
    Blue = color.blue*255 + 0.5;
    char hexColor[8];
    std::snprintf(hexColor, sizeof hexColor, "#%02x%02x%02x", Red, Green, Blue);
    //deadbeef->conf_set_str("lyricbar.backgroundcolor", hexColor);
}

void on_Highlight_color_color_set(GtkColorButton* c) {
    GdkRGBA color;
    int Red, Green, Blue;
    gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(c), &color);
    Red = color.red * 255 + 0.5;
    Green = color.green * 255 + 0.5;
    Blue = color.blue * 255 + 0.5;
    char hexColor[8];
    std::snprintf(hexColor, sizeof hexColor, "#%02x%02x%02x", Red, Green, Blue);
    //deadbeef->conf_set_str("lyricbar.highlightcolor", hexColor);
}

void on_Text_color_color_set(GtkColorButton* c) {
    GdkRGBA color;
    int Red, Green, Blue;
    gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(c), &color);
    Red = color.red * 255 + 0.5;
    Green = color.green * 255 + 0.5;
    Blue = color.blue * 255 + 0.5;
    char hexColor[8];
    std::snprintf(hexColor, sizeof hexColor, "#%02x%02x%02x", Red, Green, Blue);
    //deadbeef->conf_set_str("lyricbar.regularcolor", hexColor);
}


void on_Align_toggled(GtkRadioButton* b) {

    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b))) {
        if (strcmp(gtk_button_get_label(GTK_BUTTON(b)), "Left") == 0) {
            Align_int_value = 0;
        }
        else if (strcmp(gtk_button_get_label(GTK_BUTTON(b)), "Center") == 0) {
            Align_int_value = 1;
        }
        else if (strcmp(gtk_button_get_label(GTK_BUTTON(b)), "Right") == 0) {
            Align_int_value = 2;
        }
    }
}

void on_check_bold_toggled(GtkCheckButton *b) {
    
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b))){
        //deadbeef->conf_set_int("lyricbar.bold", 1);
    }
    else{
        //deadbeef->conf_set_int("lyricbar.bold", 0);
    }
}

void on_Cancel_clicked (GtkButton *b, gpointer user_data) {
    gtk_window_close(GTK_WINDOW(user_data));
}

void on_Apply_clicked(GtkButton* b) {
    //deadbeef->conf_set_int("lyricbar.lyrics.alignment", Align_int_value);
    //deadbeef->conf_set_int("lyricbar.vpostion", gtk_spin_button_get_value (GTK_SPIN_BUTTON(Highlight_line)));
    //deadbeef->conf_set_int("lyricbar.border", gtk_spin_button_get_value (GTK_SPIN_BUTTON(Edge)));
    printf("%s \n", "Apply clicked");
    //get_tags();
    ////gtk_label_set_text (GTK_LABEL(Title), (const gchar* ) "Apply");
}

void on_OK_clicked (GtkButton *b, gpointer user_data) {
    on_Apply_clicked (b);
    gtk_window_close(GTK_WINDOW(user_data));
    //gtk_label_set_text (GTK_LABEL(Title), (const gchar* ) "OK");
}

void set_chooser_color(GtkColorButton *chooser, const char *hexColor ){
    int red,green,blue;
    sscanf(hexColor, "#%02x%02x%02x", &red, &green, &blue);
    double Double_red = red;
    Double_red = Double_red/255;
    double Double_green = green;
    Double_green = Double_green/255;
    double Double_blue = blue;
    Double_blue = Double_blue/255;
    double Alpha = 1;

    const GdkRGBA* color = new GdkRGBA{Double_red,Double_green,Double_blue,Alpha};
    gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(chooser),color);
    
}

int on_button_config (GtkMenuItem *menuitem, gpointer user_data) {

//---------------------------------------------------------------------
// establish contact with xml code used to adjust widget settings
//---------------------------------------------------------------------

    builder = gtk_builder_new_from_resource ("/src/panels.glade");
 
    ConfigWindow = GTK_WINDOW(gtk_builder_get_object(builder, "ConfigWindow"));

// Widgets creation:
    Background_color   = GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "Background_color"));
    Highlight_color   = GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "Highlight_color"));
    Text_color     = GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "Text_color"));
    Highlight_line    = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "Highlight_line"));
    Check_bold    = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, "Check_bold"));
    Edge      = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "Edge"));
    Align_left     = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "Align_left"));
    Align_center    = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "Align_center"));
    Align_right    = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "Align_right"));
    OK       = GTK_BUTTON(gtk_builder_get_object(builder, "OK"));
    Cancel      = GTK_BUTTON(gtk_builder_get_object(builder, "Cancel"));
    Apply      = GTK_BUTTON(gtk_builder_get_object(builder, "Apply"));
    Background_color_label = GTK_LABEL(gtk_builder_get_object(builder, "Background_color_label"));
    Text_color_label  = GTK_LABEL(gtk_builder_get_object(builder, "Text_color_label"));
    Highlight_color_label = GTK_LABEL(gtk_builder_get_object(builder, "Highlight_color_label"));
    Align_label    = GTK_LABEL(gtk_builder_get_object(builder, "Align_label"));
    Edge_label    = GTK_LABEL(gtk_builder_get_object(builder, "Edge_label"));
    Highlight_line_label = GTK_LABEL(gtk_builder_get_object(builder, "Highlight_line_label"));


// Translation:
    //if (strcmp(locale_lang , "zh_CN.UTF-8") == 0) {
    //    gtk_label_set_label(Background_color_label, "背景颜色: ");
    //    gtk_label_set_label(Text_color_label, "文本颜色: ");
    //    gtk_label_set_label(Highlight_color_label, "高亮颜色: ");
    //    gtk_label_set_label(Align_label, "对齐方式: ");
    //    gtk_label_set_label(Edge_label, "边距: ");
    //    gtk_label_set_label(Highlight_line_label, "高亮行行高 %: ");
    //    gtk_button_set_label(GTK_BUTTON(Check_bold), "加粗");
    //    gtk_button_set_label(GTK_BUTTON(Align_left), "左对齐");
    //    gtk_button_set_label(GTK_BUTTON(Align_center), "居中");
    //    gtk_button_set_label(GTK_BUTTON(Align_right), "右对齐");
    //    gtk_button_set_label(GTK_BUTTON(OK), "确认");
    //    gtk_button_set_label(GTK_BUTTON(Cancel), "取消");
    //    gtk_button_set_label(GTK_BUTTON(Apply), "应用");
    //    gtk_window_set_title(ConfigWindow, "设置");
    //}

    gtk_radio_button_join_group(Align_center, Align_left);
    gtk_radio_button_join_group(Align_right, Align_left);

// Signals:
    g_signal_connect(ConfigWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_builder_connect_signals(builder, NULL);
    g_signal_connect(Background_color, "color-set", G_CALLBACK(on_Background_color_color_set), NULL);
    g_signal_connect(Highlight_color, "color-set", G_CALLBACK(on_Highlight_color_color_set), NULL);
    g_signal_connect(Text_color, "color-set", G_CALLBACK(on_Text_color_color_set), NULL);
    g_signal_connect(Align_left, "toggled", G_CALLBACK(on_Align_toggled), NULL);
    g_signal_connect(Align_center, "toggled", G_CALLBACK(on_Align_toggled), NULL);
    g_signal_connect(Align_right, "toggled", G_CALLBACK(on_Align_toggled), NULL);
    g_signal_connect(Check_bold, "toggled", G_CALLBACK(on_check_bold_toggled), NULL);
    g_signal_connect(OK, "clicked", G_CALLBACK(on_OK_clicked), ConfigWindow);
    g_signal_connect(Cancel, "clicked", G_CALLBACK(on_Cancel_clicked), ConfigWindow);
    g_signal_connect(Apply, "clicked", G_CALLBACK(on_Apply_clicked), NULL);


//// Saved color to choosers:
//    set_chooser_color(Background_color, deadbeef->conf_get_str_fast("lyricbar.backgroundcolor", "#F6F6F6"));
//    set_chooser_color(Highlight_color, deadbeef->conf_get_str_fast("lyricbar.highlightcolor", "#571c1c"));
//    set_chooser_color(Text_color, deadbeef->conf_get_str_fast("lyricbar.regularcolor", "#000000"));
//
//// Saved value to spin buttons:
//    gtk_spin_button_set_value(Highlight_line, deadbeef->conf_get_int("lyricbar.vpostion", 50));
//    gtk_spin_button_set_value(Edge, deadbeef->conf_get_int("lyricbar.border", 22));
//
//// Saved value to check button:
//
//    Check_bold_int_value = deadbeef->conf_get_int("lyricbar.bold", 1);

    if (Check_bold_int_value == 1){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Check_bold), TRUE);
    }
    else{
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Check_bold), FALSE); 
    }

//// Saved value to radio buttons:
//    Align_int_value = deadbeef->conf_get_int("lyricbar.lyrics.alignment", 1);

    if (Align_int_value == 0){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Align_left), TRUE);  
    }
    else if (Align_int_value == 1){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Align_center), TRUE);
    }
    else if (Align_int_value == 2){
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Align_right), TRUE);
    }

    
    gtk_widget_show(GTK_WIDGET(ConfigWindow));
    gtk_widget_grab_focus(GTK_WIDGET(ConfigWindow));
    gtk_window_set_keep_above(ConfigWindow,1);

    gtk_main();

    return EXIT_SUCCESS;
}

//---------------------------------------------------------------------
//******************* \ConfigWindow ***********************************
//---------------------------------------------------------------------


//---------------------------------------------------------------------
//******************* SearchWindow ************************************
//---------------------------------------------------------------------

gchar* specialtoplus(const gchar* text) {
    gchar* counter = g_strdup(text);
    // for(unsigned i = 0; i < strlen(counter); i++)
    // {
    //     if( (counter[i] < 'A' ||  counter[i] > 'Z') &&  (counter[i] < 'a' ||  counter[i] > 'z') &&  (counter[i] < '0' ||  counter[i] > '9')) {  
    //         counter[i] = '+';
    //  }
    // }
    return counter;
}

void populate_tree_view(GList* songs, const gchar* source) {
    GList* iter = songs;
    gint count = 0;
    while (iter != NULL) {
        if (count % 4 == 0) {
            gtk_tree_store_append (treeStore, &iter_populate, NULL);
            gtk_tree_store_set(treeStore, &iter_populate, 0, (gchar*)iter->data, -1);
        } else if (count % 4 == 1) {
            gtk_tree_store_set(treeStore, &iter_populate, 1, (gchar*)iter->data, -1);
        } else if (count % 4 == 2) {
            gtk_tree_store_set(treeStore, &iter_populate, 2, (gchar*)iter->data, -1);
        } else if (count % 4 == 3) {
            gtk_tree_store_set(treeStore, &iter_populate, 3, source, -1);
            gtk_tree_store_set(treeStore, &iter_populate, 4, (gchar*)iter->data, -1);
        }
        iter = iter->next;
        count++;
    }
/*
      <!-- column-name Artist -->
      <column type="gchararray"/>
      <!-- column-name Song -->
      <column type="gchararray"/>
      <!-- column-name Album -->
      <column type="gchararray"/>
      <!-- column-name Source -->
      <column type="gchararray"/>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
 */
}

void on_Save_clicked(GtkButton* b, gpointer user_data) {
    LyricWidget* widget = (LyricWidget*)user_data;

    gchar* lrc_path = get_lrc_path(widget->location);
    write_to_file(lrc_path, selected_lyrics.lyrics);
    g_free(lrc_path);
}


// 用于传递给线程的数据结构
struct LyricsDownloadData {
    gchar* provider;
    gchar* value;
    GtkLabel* preview_label;
};

// 用于更新UI的回调数据
struct UpdateUIData {
    gchar* lyrics;
    GtkLabel* preview_label;
};

// UI更新回调函数（在主线程中执行）
static gboolean update_lyrics_label(gpointer user_data) {
    UpdateUIData* data = static_cast<UpdateUIData*>(user_data);
    
    if (data && data->preview_label) {
        // 更新全局变量
        g_free(selected_lyrics.lyrics);
        selected_lyrics.lyrics = g_strdup(data->lyrics);
        selected_lyrics.sync = (data->lyrics && strlen(data->lyrics) > 0);
        
        // 更新UI
        gtk_label_set_label(data->preview_label, data->lyrics);
    }
    
    // 清理内存
    g_free(data->lyrics);
    delete data;
    return G_SOURCE_REMOVE;
}

// 在线程中执行的下载函数
void download_lyrics_in_thread(gpointer user_data) {
    LyricsDownloadData* download_data = static_cast<LyricsDownloadData*>(user_data);
    struct parsed_lyrics result = {g_strdup(""), FALSE};
    
    // 在线程中执行下载
    if (g_strcmp0(download_data->provider, "Kugou") == 0) {
        result = kugou_lyrics_downloader(download_data->value);
    }
    
    // 创建UI更新数据
    UpdateUIData* update_data = new UpdateUIData;
    update_data->lyrics = g_strdup(result.lyrics);
    update_data->preview_label = download_data->preview_label;
    
    // 使用g_idle_add将UI更新调度回主线程
    g_idle_add(update_lyrics_label, update_data);
    
    // 清理下载数据
    delete download_data;
}

void on_row_double_clicked (GtkButton *b) {
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(SongsTree));
    gchar *provider, *value;
    GtkTreeIter iter;
    GtkTreeModel *model;

    if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter) == FALSE){
        return;
    }
    gtk_tree_model_get(model, &iter, 3, &provider,  -1);
    gtk_tree_model_get(model, &iter, 4, &value,  -1);

    // 显示加载提示
    gtk_label_set_label(PreViewLyrics, "正在下载歌词...");

    // 准备下载数据
    LyricsDownloadData* download_data = new LyricsDownloadData;
    download_data->provider = g_strdup(provider);
    download_data->value = g_strdup(value);
    download_data->preview_label = PreViewLyrics;
    
    // 释放GTK分配的内存
    g_free(provider);
    g_free(value);
    
    // 在新线程中执行下载
    std::thread download_thread(download_lyrics_in_thread, download_data);
    download_thread.detach();
}

void thread_listener_slow(gchar* text_song, gchar* text_artist){
    //GList* megalobiz_songs = megalobiz_get_songs(text_song, text_artist);
    //populate_tree_view(megalobiz_songs, "Megalobiz");
    //g_list_free_full(megalobiz_songs, g_free);
}

void thread_listener_fast(gchar* text_song, gchar* text_artist){
    //// debug_out << "thread_listener_fast" <<  text_song << ", " << text_artist << std::endl;

    GList* kugou_songs = kugou_get_songs(text_song, text_artist);
    populate_tree_view(kugou_songs, "Kugou");
    g_list_free_full(kugou_songs, g_free);

    //std::vector<std::string> spotify_songs =  spotify_get_songs(text_song, text_artist);
    //populate_tree_view(spotify_songs, "Spotify");

    //std::vector<std::string> azlyrics_songs = azlyrics_get_songs(text_song, text_artist);
    //populate_tree_view(azlyrics_songs, "AZlyrics");
}


void on_Search_clicked (GtkButton *b) {
//    // debug_out << "lyricbar > on_Search_clicked" << std::endl;
    gtk_tree_store_clear(treeStore);
    gchar* text_artist, *text_song, *text_album;

    text_artist = specialtoplus(gtk_entry_get_text(Artist_input));
    text_song = specialtoplus(gtk_entry_get_text(Song_input));
    text_album = specialtoplus(gtk_entry_get_text(Album_input));
//    debug_out << text_artist << ": " << text_song << std::endl;

    std::thread t1(thread_listener_fast, text_song, text_artist);
    //std::thread t2(thread_listener_slow, text_song,text_artist);
    t1.detach(); // 分离线程，让它在后台运行

    // 清理内存
    g_free(text_artist);
    g_free(text_song);
    g_free(text_album);

//// printf("Songs  = %s\n; ", songs);
//    //gtk_label_set_text (GTK_LABEL(Title), (const gchar* ) "OK");

}

void on_Exit_clicked (GtkButton *b, gpointer user_data) {
    gtk_window_close(GTK_WINDOW(user_data));
}


int on_button_search (GtkMenuItem *menuitem, gpointer user_data) {

    builder = gtk_builder_new_from_resource ("/src/panels.glade");

    SearchWindow = GTK_WINDOW(gtk_builder_get_object(builder, "SearchWindow"));

// Widgets creation:
    Artist_input  = GTK_ENTRY(gtk_builder_get_object(builder, "Artist_input"));
    Song_input   = GTK_ENTRY(gtk_builder_get_object(builder, "Song_input"));
    Album_input   = GTK_ENTRY(gtk_builder_get_object(builder, "Album_input"));
    treeStore   = GTK_TREE_STORE(gtk_builder_get_object(builder, "treeStore"));
    SongsTree   = GTK_TREE_VIEW(gtk_builder_get_object(builder, "SongsTree"));
    Column_artist  = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "Column_artist"));
    Column_song   = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "Column_song"));
    Column_album  = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "Column_album"));
    Column_source  = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "Column_source"));
    Column_searchid  = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "Column_searchid"));
    artists    = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "artists"));
    songs    = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "songs"));
    albums    = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "albums"));
    sources    = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "sources"));
    searchids   = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "searchids"));
    selection   = GTK_TREE_SELECTION(gtk_builder_get_object(builder, "selection"));
    PreViewLyrics  = GTK_LABEL(gtk_builder_get_object(builder, "PreViewLyrics"));
    Artist_label  = GTK_LABEL(gtk_builder_get_object(builder, "Artist_label"));
    Song_label   = GTK_LABEL(gtk_builder_get_object(builder, "Song_label"));
    Album_label   = GTK_LABEL(gtk_builder_get_object(builder, "Album_label"));
    Save    = GTK_BUTTON(gtk_builder_get_object(builder, "Save"));
    Exit    = GTK_BUTTON(gtk_builder_get_object(builder, "Exit"));
    Search    = GTK_BUTTON(gtk_builder_get_object(builder, "Search"));

    LyricWidget* widget = (LyricWidget*)user_data;
    gtk_entry_set_text(Artist_input, widget->artist);
    gtk_entry_set_text(Song_input, widget->title);
    //gtk_entry_set_text(Album_input, widget->album); 
    
    gtk_tree_view_set_activate_on_single_click(SongsTree, FALSE);
    gtk_tree_view_column_add_attribute(Column_artist, artists, "text", 0);
    gtk_tree_view_column_add_attribute(Column_song, songs, "text", 1);
    gtk_tree_view_column_add_attribute(Column_album, albums, "text", 2);
    gtk_tree_view_column_add_attribute(Column_source, sources, "text", 3);
    gtk_tree_view_column_add_attribute(Column_searchid, searchids, "text", 4); 
    gtk_tree_view_column_set_visible(Column_searchid,FALSE);
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(SongsTree));

// Signals:
    g_signal_connect(SearchWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_builder_connect_signals(builder, NULL);
    g_signal_connect(SongsTree, "row-activated", G_CALLBACK(on_row_double_clicked), selection);
    g_signal_connect(Save, "clicked", G_CALLBACK(on_Save_clicked), user_data); //track
    g_signal_connect(Exit, "clicked", G_CALLBACK(on_Exit_clicked), SearchWindow);
    g_signal_connect(Search, "clicked", G_CALLBACK(on_Search_clicked), NULL);

    gtk_widget_show(GTK_WIDGET(SearchWindow));
    gtk_widget_grab_focus(GTK_WIDGET(SearchWindow));
    gtk_window_set_keep_above(SearchWindow,1);

    gtk_main();
    
    return EXIT_SUCCESS;
}


//---------------------------------------------------------------------
//******************* \SearchWindow ***********************************
//---------------------------------------------------------------------


//---------------------------------------------------------------------
//******************* EditWindow **************************************
//---------------------------------------------------------------------

void splitstr(gchar* text, const gchar* delimiter) {
    gint start = 0;
    gchar* pos = g_strstr_len(text + start, -1, delimiter);
    while (pos != NULL) {
        start = (pos - text) + strlen(delimiter);
        pos = g_strstr_len(text + start, -1, delimiter);
    }
}

gchar* apply_delay(gchar* lyrics, gint delay){
    GString* lyrics_delayed = g_string_new("");
    gchar** lines = g_strsplit(lyrics, "\n", -1);
    
    for (gint i = 0; lines[i] != NULL; i++) {
        gchar* line = lines[i];
        gsize line_len = strlen(line);
        
        if (line_len > 9 && line[0] == '[' && line[3] == ':' && line[6] == '.') {
            gint seconds;
            gint minutes;
            minutes = (line[1] - 48) * 10 + (line[2] - 48);
            seconds = (line[4] - 48) * 1000 + (line[5] - 48) * 100 + (line[7] - 48) * 10 + (line[8] - 48) + delay;
            
            // Avoid negative timestamps
            gchar* time_line;
            if (minutes * 60000 + seconds * 10 > 0) {
                time_line = timestamps(minutes * 60000 + seconds * 10);
            } else {
                time_line = timestamps(0);
            }
            
            gchar* text_line = g_strndup(line + 10, line_len - 10);
            g_string_append_printf(lyrics_delayed, "%s%s\n", time_line, text_line);
            g_free(time_line);
            g_free(text_line);
        } else {
            g_string_append_printf(lyrics_delayed, "%s\n", line);
        }
    }
    
    g_strfreev(lines);
    return g_string_free(lyrics_delayed, FALSE);
}

void update_text_textview(const gchar* text) {
    GtkTextIter Start_iter, Finish_iter;
    gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(refBuffer), &Start_iter);
    gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER(refBuffer), &Finish_iter);
    gtk_text_buffer_delete(GTK_TEXT_BUFFER(refBuffer),&Start_iter, &Finish_iter);

    gtk_text_buffer_insert(GTK_TEXT_BUFFER(refBuffer), &Start_iter, text, -1);
}

gchar* get_text_textview() {
    GtkTextIter Start_iter, Finish_iter;
    gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(refBuffer), &Start_iter);
    gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(refBuffer), &Finish_iter);
    gchar* text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(refBuffer),&Start_iter, &Finish_iter, FALSE);
    return text;
}

int power(int base, int exponent) {
    int i = 0, result = 1;
    while (i < exponent) {
        result = result * base;
        i++;
    }
    return result;
}

gchar* apply_offset(gchar* lyrics) {
    const gchar* offset = "[offset:";
    const gchar* squarebracket = "]";
    GString* lyrics_delayed = g_string_new("");
    gchar* line;
    gint delay = 0;
    gchar* offset_pos = g_strstr_len(lyrics, -1, offset);

    if (offset_pos) {
        gsize prefix_len = offset_pos - lyrics;
        line = g_strndup(lyrics, prefix_len);
        g_string_append(lyrics_delayed, line);
        g_free(line);

        gchar* bracket_pos = g_strstr_len(offset_pos + strlen(offset), -1, squarebracket);
        if (bracket_pos) {
            gsize delay_len = bracket_pos - (offset_pos + strlen(offset));
            line = g_strndup(offset_pos + strlen(offset), delay_len);
            gint negative_or_not = 1;
            
            if (line[0] == '-') {
                gchar* temp = g_strdup(line + 1);
                g_free(line);
                line = temp;
                negative_or_not = -1;
            }

            for (gsize i = 0; i < strlen(line); i++) {
                delay = delay + (line[i] - 48) * power(10, strlen(line) - 1 - i);
            }

            delay = delay * negative_or_not / 10;
            g_free(line);

            gchar* remaining = g_strdup(bracket_pos + strlen(squarebracket));
            gchar* delayed = apply_delay(g_string_free(lyrics_delayed, FALSE), delay);
            lyrics_delayed = g_string_new(delayed);
            g_string_append(lyrics_delayed, remaining);
            g_free(delayed);
            g_free(remaining);
        } else {
            g_string_append(lyrics_delayed, offset_pos);
        }
    } else {
        g_string_append(lyrics_delayed, lyrics);
    }

    return g_string_free(lyrics_delayed, FALSE);
}


void on_Backward_clicked (GtkButton *b) {
    //float percent = deadbeef->playback_get_pos();
    //if (percent > 0.5){
    //    deadbeef->playback_set_pos( percent - 0.5 );
    //}
}

void on_Pause_play_clicked (GtkButton *b) {
    //deadbeef->sendmessage( DB_EV_TOGGLE_PAUSE, 0, 0, 0 );
}

void on_Forward_clicked (GtkButton *b) {
    //float percent = deadbeef->playback_get_pos();
    //if (percent < 99.5){
    //    deadbeef->playback_set_pos( percent + 0.5 );
    //}
}

void on_Plus_time_clicked (GtkButton *b) {
    gchar* text = get_text_textview();
    gchar* delayed_text = apply_delay(text, 10);
    update_text_textview(delayed_text);
    g_free(text);
    g_free(delayed_text);
}

void on_Minus_time_clicked (GtkButton *b) {
    gchar* text = get_text_textview();
    gchar* delayed_text = apply_delay(text, -10);
    update_text_textview(delayed_text);
    g_free(text);
    g_free(delayed_text);
}

void on_Apply_offset_clicked (GtkButton *b) {
    gchar* text = get_text_textview();
    gchar* offset_text = apply_offset(text);
    update_text_textview(offset_text);
    g_free(text);
    g_free(offset_text);
}

gchar *actual_track_time() {
    gchar *text;
    float pos = 0; //TODO deadbeef->streamer_get_playpos();
    int minutes = pos / 60;
    pos = pos - minutes*60;
    if (minutes < 10){
        text = g_strdup_printf ("0%i:%05.2f", minutes,pos);
    }
    else{
        text = g_strdup_printf ("%i:%05.2f", minutes,pos);
    }
    return text;
}

void on_Insert_timestamp_clicked (GtkButton *b) {
    GtkTextIter iter;
    gchar* time = actual_track_time();
    gchar* timestamp = g_strdup_printf("\n[%s]", time);
    gtk_text_buffer_get_iter_at_mark(refBuffer, &iter, gtk_text_buffer_get_insert(refBuffer));
    gtk_text_iter_forward_to_line_end (&iter);
    gtk_text_buffer_insert(GTK_TEXT_BUFFER(refBuffer), &iter, timestamp, -1);
    g_free(time);
    g_free(timestamp);
}

static gboolean on_timeout (gpointer user_data) {
    GtkLabel *label = GTK_LABEL(user_data);
    gchar *text = actual_track_time();
    gchar* playback_time;
    
    if (g_strcmp0(locale_lang, "zh_CN.UTF-8") == 0) {
        playback_time = g_strdup_printf("播放: %s ", text);
    } else {
        playback_time = g_strdup_printf("Playback: %s ", text);
    }
    
    gtk_label_set_label (label, playback_time);
    g_free(text);
    g_free(playback_time);

    return G_SOURCE_CONTINUE; /* or G_SOURCE_REMOVE when you want to stop */
}



void on_Edit_cancel_clicked (GtkButton *b, gpointer user_data) {
    gtk_window_close(GTK_WINDOW(user_data));
}

void on_Edit_apply_clicked (GtkButton *b) {
    gboolean sync = FALSE;
    gchar* text = get_text_textview();
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Check_sync))){
        sync = TRUE;
    }
    //DB_playItem_t *track = deadbeef->streamer_get_playing_track_safe();
    //save_meta_data(track, {text, sync});
    //deadbeef->pl_item_unref(track);
    g_free(text);
}

void on_Edit_OK_clicked (GtkButton *b, gpointer user_data) {
    
    on_Edit_apply_clicked (b);
    gtk_window_close(GTK_WINDOW(user_data));
}

int on_button_edit (GtkMenuItem *menuitem, gpointer user_data) {

    builder = gtk_builder_new_from_resource ("/src/panels.glade");

    EditWindow = GTK_WINDOW(gtk_builder_get_object(builder, "EditWindow"));

// Widgets creation:
    Text_view_lyrics_editor = GTK_TEXT_VIEW(gtk_builder_get_object(builder, "Text_view_lyrics_editor"));
    Backward    = GTK_BUTTON(gtk_builder_get_object(builder, "Backward"));
    Pause_play    = GTK_BUTTON(gtk_builder_get_object(builder, "Pause_play"));
    Forward     = GTK_BUTTON(gtk_builder_get_object(builder, "Forward"));
    Playback_time   = GTK_LABEL(gtk_builder_get_object(builder, "Playback_time"));
    Plus_time    = GTK_BUTTON(gtk_builder_get_object(builder, "Plus_time"));
    Minus_time    = GTK_BUTTON(gtk_builder_get_object(builder, "Minus_time"));
    Apply_offset   = GTK_BUTTON(gtk_builder_get_object(builder, "Apply_offset"));
    Insert_timestamp  = GTK_BUTTON(gtk_builder_get_object(builder, "Insert_timestamp"));
    Check_sync    = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, "Check_sync"));
    Edit_apply    = GTK_BUTTON(gtk_builder_get_object(builder, "Edit_apply"));
    Edit_cancel    = GTK_BUTTON(gtk_builder_get_object(builder, "Edit_cancel"));
    Edit_OK     = GTK_BUTTON(gtk_builder_get_object(builder, "Edit_OK"));
    Sync_label    = GTK_LABEL(gtk_builder_get_object(builder, "Sync_label"));
    Sync_or_not_label  = GTK_LABEL(gtk_builder_get_object(builder, "Sync_or_not_label"));

// Translation:
    //if (strcmp(locale_lang , "zh_CN.UTF-8") == 0) {
    //    gtk_label_set_label(Sync_label, "同步 ");
    //    gtk_label_set_label(Sync_or_not_label, "是否同步 ");
    //    gtk_label_set_label (Playback_time, "播放: 00:00.00");
    //    gtk_button_set_label(GTK_BUTTON(Pause_play), "播放/暂停");
    //    gtk_button_set_label(GTK_BUTTON(Plus_time), "+ 0.1 秒");
    //    gtk_button_set_label(GTK_BUTTON(Minus_time), "- 0.1 秒");
    //    gtk_button_set_label(GTK_BUTTON(Apply_offset), "应用偏移");
    //    gtk_button_set_label(GTK_BUTTON(Insert_timestamp), "插入时间戳");
    //    gtk_button_set_label(GTK_BUTTON(Check_sync), "同步歌词");
    //    gtk_button_set_label(GTK_BUTTON(Edit_apply), "应用");
    //    gtk_button_set_label(GTK_BUTTON(Edit_cancel), "取消");
    //    gtk_button_set_label(GTK_BUTTON(Edit_OK), "确认");
    //    gtk_window_set_title(EditWindow, "编辑");
    //}

    //DB_playItem_t *track = deadbeef->streamer_get_playing_track_safe();
    //struct parsed_lyrics track_lyrics;

    //if (track){
    //    track_lyrics = get_lyrics_from_metadata(track);
    //    deadbeef->pl_item_unref(track); 
    //}

    //refBuffer = gtk_text_view_get_buffer(Text_view_lyrics_editor);
    //update_text_textview(track_lyrics.lyrics);


// Signals:
    g_signal_connect(EditWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_builder_connect_signals(builder, NULL);

    g_signal_connect(Backward, "clicked", G_CALLBACK(on_Backward_clicked), NULL);
    g_signal_connect(Pause_play, "clicked", G_CALLBACK(on_Pause_play_clicked), NULL);
    g_signal_connect(Forward, "clicked", G_CALLBACK(on_Forward_clicked), NULL);
    g_timeout_add (10 /* milliseconds */, on_timeout, Playback_time);
    g_signal_connect(Plus_time, "clicked", G_CALLBACK(on_Plus_time_clicked), NULL);
    g_signal_connect(Minus_time, "clicked", G_CALLBACK(on_Minus_time_clicked), NULL);
    g_signal_connect(Apply_offset, "clicked", G_CALLBACK(on_Apply_offset_clicked), NULL);
    g_signal_connect(Insert_timestamp, "clicked", G_CALLBACK(on_Insert_timestamp_clicked), NULL);
    g_signal_connect(Edit_apply, "clicked", G_CALLBACK(on_Edit_apply_clicked), NULL);
    g_signal_connect(Edit_cancel, "clicked", G_CALLBACK(on_Edit_cancel_clicked), EditWindow);
    g_signal_connect(Edit_OK, "clicked", G_CALLBACK(on_Edit_OK_clicked), EditWindow);

//// Sync value to check button:
//    if (track_lyrics.sync == true){
//        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Check_sync), TRUE);
//    }
//    else{
//        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Check_sync), FALSE); 
//    }

// Always on top.
    gtk_widget_show(GTK_WIDGET(EditWindow));
    gtk_widget_grab_focus(GTK_WIDGET(EditWindow));
    gtk_window_set_keep_above(EditWindow,1);

    gtk_main();
    
    return EXIT_SUCCESS;
}


//---------------------------------------------------------------------
//******************* \EditWindow *************************************
//---------------------------------------------------------------------
